home *** CD-ROM | disk | FTP | other *** search
/ Visual Cafe 3 / Visual Cafe 3.ISO / Vcafe / Main.bin / RMISecurityManager.java < prev    next >
Text File  |  1998-09-22  |  13KB  |  443 lines

  1. /*
  2.  * @(#)RMISecurityManager.java    1.13 98/09/02
  3.  *
  4.  * Copyright 1995-1998 by Sun Microsystems, Inc.,
  5.  * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
  6.  * All rights reserved.
  7.  * 
  8.  * This software is the confidential and proprietary information
  9.  * of Sun Microsystems, Inc. ("Confidential Information").  You
  10.  * shall not disclose such Confidential Information and shall use
  11.  * it only in accordance with the terms of the license agreement
  12.  * you entered into with Sun.
  13.  */
  14.  
  15. package java.rmi;
  16.  
  17. import java.net.URL;
  18. import java.net.InetAddress;
  19. import java.net.UnknownHostException;
  20. import java.io.FileDescriptor;
  21. import java.rmi.server.RMIClassLoader;
  22.  
  23. /**
  24.  * This class defines a default security policy for RMI applications (not
  25.  * applets).  For code loaded from a class loader, the security manager
  26.  * disables all functions except class definition and access.  This class
  27.  * may be subclassed to implement a different policy.  To set a
  28.  * RMISecurityManager, add the following to an application's main()
  29.  * method: <br>
  30.  * 
  31.  * System.setSecurityManager(new RMISecurityManager()); If no security
  32.  * manager has been set, RMI will only load classes from local system
  33.  * files as defined by CLASSPATH.<p>
  34.  *
  35.  * @version    1.13, 09/02/98
  36.  * @author Roger Riggs
  37.  */
  38. public class RMISecurityManager extends SecurityManager {
  39.     
  40.     /**
  41.      * Construct and initialize.
  42.      */
  43.     public RMISecurityManager() {
  44.     // XXX: DO NOT REMOVE THIS IN 1.1.X. This call indirectly
  45.     // initializes java.security.Security, which cannot be done
  46.     // while a security manager is installed and a classloader is
  47.     // on the stack.
  48.     java.security.Security.getProviders();
  49.     }
  50.  
  51.     /**
  52.      * True if called indirectly from a loaded class.
  53.      */
  54.     private boolean inLoadedClass() {
  55.     return inClassLoader();
  56.     }
  57.  
  58.     /**
  59.      * Returns the security context (e.g., a URL).
  60.      */
  61.     public Object getSecurityContext() {
  62.     return RMIClassLoader.getSecurityContext(currentClassLoader());
  63.     }
  64.  
  65.  
  66.     /**
  67.      * Loaded classes are not allowed to create class loaders, or even
  68.      * execute any of ClassLoader's methods.
  69.      */
  70.     public synchronized void checkCreateClassLoader() {
  71.     if (inLoadedClass()) {
  72.         throw new RMISecurityException("classloader");
  73.     }
  74.     }
  75.  
  76.     /**
  77.      * Loaded classes are not allowed to manipulate threads.
  78.      */
  79.     public synchronized void checkAccess(Thread t) {
  80.     if (inLoadedClass() && classLoaderDepth() == 3) {
  81.         throw new RMISecurityException("thread");
  82.     }
  83.     }
  84.  
  85.     /**
  86.      * Loaded classes are not allowed to manipulate thread groups.
  87.      */
  88.     public synchronized void checkAccess(ThreadGroup g) {
  89.     if (inLoadedClass() && classLoaderDepth() == 4) {
  90.         throw new RMISecurityException("threadgroup");
  91.     }
  92.     }
  93.  
  94.     /**
  95.      * Loaded classes are not allowed to exit the VM.
  96.      */
  97.     public synchronized void checkExit(int status) {
  98.     if (inLoadedClass()) {
  99.         throw new RMISecurityException("exit", String.valueOf(status));
  100.     }
  101.     }
  102.  
  103.     /**
  104.      * Loaded classes are not allowed to fork processes.
  105.      */
  106.     public synchronized void checkExec(String cmd){
  107.     if (inLoadedClass()) {
  108.         throw new RMISecurityException("exec", cmd);
  109.     }
  110.     }
  111.  
  112.     /**
  113.      * Loaded classes are not allowed to link dynamic libraries.
  114.      */
  115.     public synchronized void checkLink(String lib){
  116.     switch (classLoaderDepth()) {
  117.       case 2: // Runtime.load
  118.       case 3: // System.loadLibrary
  119.         throw new RMISecurityException("link", lib);
  120.       default:
  121.         break;
  122.     }
  123.     }
  124.  
  125.     /**
  126.      * Loaded classes are not allowed to access the system properties list.
  127.      */
  128.     public synchronized void checkPropertiesAccess() {
  129.     if (classLoaderDepth() == 2) {
  130.         throw new RMISecurityException("properties");
  131.     }
  132.     }
  133.  
  134.     /**
  135.      * Loaded classes can access the system property named by <i>key</i>
  136.      * only if its twin <i>key.rmi</i> property is set to true.
  137.      * For example, the property <code>java.home</code> can be read by
  138.      * loaded classes only if <code>java.home.rmi</code> is <code>true</code>.
  139.      */
  140.     public synchronized void checkPropertyAccess(String key) {
  141.     if (classLoaderDepth() == 2) {
  142.         if (!"true".equalsIgnoreCase(System.getProperty(key + ".rmi"))) {
  143.         throw new RMISecurityException("properties");
  144.             }
  145.     }
  146.     }
  147.  
  148.     /**
  149.      * Check if a loaded class can read a particular file.
  150.      */
  151.     public synchronized void checkRead(String file) {
  152.     if (inLoadedClass())
  153.         throw new RMISecurityException("file.read", file);
  154.     }
  155.  
  156.     /**
  157.      * No file reads are valid from a loaded class.
  158.      * @exception  RMISecurityException If called from a loaded class.
  159.      */
  160.     public void checkRead(String file, Object context) {
  161.     if (inLoadedClass())
  162.         throw new RMISecurityException("file.read", file);
  163.     }
  164.  
  165.     /**
  166.      * Check if a loaded class can write a particular file.
  167.      * @exception  RMISecurityException If called from a loaded class.
  168.      */
  169.     public synchronized void checkWrite(String file) {
  170.     if (inLoadedClass()) {
  171.         throw new RMISecurityException("file.write", file);
  172.     }
  173.     }
  174.  
  175.     /**
  176.      * Check if a file with the specified system dependent
  177.      * file name can be deleted.
  178.      * @param file the system dependent file name
  179.      * @exception  RMISecurityException If the file is not found.
  180.      */
  181.     public void checkDelete(String file) {
  182.     if (inLoadedClass()) {
  183.         throw new RMISecurityException("file.delete", file);
  184.     }
  185.     }
  186.  
  187.     /**
  188.      * Loaded classes are not allowed to open descriptors for reading unless
  189.      * it is done through a socket, in which case other access
  190.      * restrictions still apply.
  191.      */
  192.     public synchronized void checkRead(FileDescriptor fd) {
  193.     if ((inLoadedClass() && !inClass("java.net.SocketInputStream"))
  194.         || (!fd.valid()) ) {
  195.         throw new RMISecurityException("fd.read");
  196.     }
  197.     }
  198.  
  199.     /**
  200.      * Loaded classes are not allowed to open descriptors for writing unless
  201.      * it is done through a socket, in which case other access
  202.      * restrictions still apply.
  203.      */
  204.     public synchronized void checkWrite(FileDescriptor fd) {
  205.     if ( (inLoadedClass() && !inClass("java.net.SocketOutputStream")) 
  206.          || (!fd.valid()) ) {
  207.         throw new RMISecurityException("fd.write");
  208.     }
  209.     }
  210.  
  211.     /**
  212.      * For now loaded classes can't listen on any port.
  213.      */
  214.     public synchronized void checkListen(int port) {
  215.     if (inLoadedClass() && port != 0 && (port < 1024 || port > 65535)) {
  216.         throw new RMISecurityException("socket.listen", String.valueOf(port));
  217.     }
  218.     }
  219.  
  220.     /**
  221.      * For now loaded classes can't accept connections on any port.
  222.      */
  223.     public synchronized void checkAccept(String host, int port) {
  224.     if (inLoadedClass()) {
  225.         throw new RMISecurityException("socket.accept", host + ":" + String.valueOf(port));
  226.     }
  227.     }
  228.  
  229.     /**
  230.      * Checks to see if current execution context is allowed to use
  231.      * (join/leave/send/receive) IP multicast (disallowed from loaded classes).
  232.      */
  233.     public void checkMulticast(InetAddress maddr) {
  234.     if (inLoadedClass()) {
  235.         throw new RMISecurityException("checkmulticast");
  236.     }
  237.     }
  238.  
  239.     /**
  240.      * Checks to see if current execution context is allowed to use
  241.      * (join/leave/send/receive) IP multicast (disallowed from loaded classes).
  242.      */
  243.     public void checkMulticast(InetAddress maddr, byte ttl) {
  244.     if (inLoadedClass()) {
  245.         throw new RMISecurityException("checkmulticast");
  246.     }
  247.     }
  248.     
  249.     /**
  250.      * Loaded classes can make connections if called through the RMI transport.
  251.      */
  252.     public synchronized void checkConnect(String host, int port) {
  253.     if (!inLoadedClass()) {
  254.         return;
  255.     }
  256.     
  257.     // REMIND: This is only appropriate for our transport
  258.     // implementation.
  259.     int depth = classDepth("sun.rmi.transport.tcp.TCPChannel");
  260.     if (depth > 1) {
  261.         // Called through our RMI transport
  262.         return;
  263.     } else {
  264.         Object url = getSecurityContext();
  265.         if (url != null && url instanceof java.net.URL) {
  266.         checkConnect(((URL)url).getHost(), host);
  267.         } else {
  268.         throw new RMISecurityException("checkConnect",
  269.                            "To " + host + ":" + port);
  270.         }
  271.     }
  272.     }
  273.     
  274.     private synchronized void checkConnect(String fromHost, String toHost) {
  275.     try {
  276.         inCheck = true;
  277.         InetAddress toHostAddr, fromHostAddr;
  278.         if (!fromHost.equals(toHost)) {
  279.         try {
  280.             // the only time we allow non-matching strings
  281.             // is when IPs and the IPs match.
  282.             toHostAddr = InetAddress.getByName(toHost);
  283.             fromHostAddr = InetAddress.getByName(fromHost);
  284.             
  285.             if (fromHostAddr.equals(toHostAddr)) {
  286.             return;
  287.             } else {
  288.             throw new RMISecurityException("checkConnect",
  289.                                "To " + toHost);
  290.             }
  291.         } catch (UnknownHostException e) {
  292.             throw new RMISecurityException("checkConnect",
  293.                            "To " + toHost);
  294.         }  
  295.         } else {
  296.         try {
  297.             toHostAddr = InetAddress.getByName(toHost);
  298.             
  299.             // strings match: if we have IP, we're homefree, 
  300.             return;
  301.         } catch (UnknownHostException e) {
  302.             throw new RMISecurityException("checkConnect",
  303.                            "To " + toHost);
  304.         }
  305.         }
  306.     } finally {
  307.         inCheck = false;
  308.     }
  309.     }
  310.     
  311.     /**
  312.      * Loaded classes can make connections if
  313.      * called through the RMI transport.
  314.      */
  315.     public void checkConnect(String host, int port, Object context) {
  316.     checkConnect(host, port);
  317.     if (context != null) {
  318.         if (context instanceof URL) {
  319.         checkConnect(((URL)context).getHost(), host);
  320.         } else {
  321.            throw new RMISecurityException("checkConnect (unknown context)",
  322.                            "To " + host);
  323.         }
  324.     }
  325.     }
  326.  
  327.     /**
  328.      * Allow caller to create top-level windows.
  329.      * Allow loaded classes to create windows with warnings.
  330.      */
  331.     public synchronized boolean checkTopLevelWindow(Object window) {
  332.     if (inLoadedClass())
  333.         return false;
  334.     return true;
  335.     }
  336.  
  337.     /**
  338.      * Check if a loaded class can access a package.
  339.      */
  340.     public synchronized void checkPackageAccess(String pkg) {
  341.  
  342.     if (!inLoadedClass())
  343.         return;
  344.     int i = pkg.indexOf('.');
  345.  
  346.     while (i > 0) {
  347.         String subpkg = pkg.substring(0, i);
  348.         if (Boolean.getBoolean("package.restrict.access." + subpkg)) {
  349.         throw new RMISecurityException("checkpackageaccess", pkg);
  350.         }
  351.         i = pkg.indexOf('.', i + 1);
  352.     }
  353.     }
  354.  
  355.     /**
  356.      * Check if a loaded class can define classes in a package.
  357.      */
  358.     public synchronized void checkPackageDefinition(String pkg) {
  359.  
  360.     if (!inLoadedClass())
  361.         return;
  362.     int i = pkg.indexOf('.');
  363.  
  364.     while (i > 0) {
  365.         String subpkg = pkg.substring(0, i);
  366.         if (Boolean.getBoolean("package.restrict.definition." + subpkg)) {
  367.         throw new RMISecurityException("checkpackagedefinition", pkg);
  368.         }
  369.         i = pkg.indexOf('.', i + 1);
  370.     }
  371.     }
  372.  
  373.     /**
  374.      * Check if a loaded class can set a networking-related object factory.
  375.      */
  376.     public synchronized void checkSetFactory() {
  377.     if (inLoadedClass()) {
  378.         throw new RMISecurityException("cannotsetfactory");
  379.     }
  380.     }
  381.  
  382.     /**
  383.      * Disallow printing from loaded classes.
  384.      */
  385.     public void checkPrintJobAccess() {
  386.     if (inLoadedClass()) {
  387.         throw new RMISecurityException("getPrintJob");
  388.     }
  389.     }
  390.  
  391.     /**
  392.      * Checks to see if an client can get access to the System Clipboard
  393.      * (disallowed from loaded classes).
  394.      */
  395.     public void checkSystemClipboardAccess() {
  396.     if (inLoadedClass()) {
  397.         throw new RMISecurityException("checksystemclipboardaccess");
  398.     }
  399.     
  400.     }
  401.  
  402.     /**
  403.      * Checks to see if an client can get access to the AWT event queue
  404.      * (disallowed from loaded classes).
  405.      */
  406.     public void checkAwtEventQueueAccess() {
  407.     if (inLoadedClass()) {
  408.         throw new RMISecurityException("checkawteventqueueaccess");
  409.     }
  410.     }
  411.  
  412.     /**
  413.      * Check if client is allowed reflective access to a member or a set
  414.      * of members for the specified class.  Once initial access is granted,
  415.      * the reflected members can be queried for identifying information, but
  416.      * can only be <strong>used</strong> (via get, set, invoke, or
  417.      * newInstance) with standard Java language access control.
  418.      *
  419.      * <p>The policy is to dent <em>untrusted</em> clients access to
  420.      * <em>declared</em> members of classes other than those loaded via
  421.      * the same class loader.  All other accesses are granted.
  422.      */
  423.     public void checkMemberAccess(Class clazz, int which) {
  424.     if (which != java.lang.reflect.Member.PUBLIC) {
  425.         ClassLoader currentLoader = currentClassLoader();
  426.         if (currentLoader != null) {
  427.         if (currentLoader != clazz.getClassLoader()) {
  428.             throw new RMISecurityException("checkmemberaccess");
  429.         }
  430.         }
  431.     }
  432.     }
  433.  
  434.     /**
  435.      * Loaded classes cannot perform security provider operations.
  436.      */
  437.     public void checkSecurityAccess(String provider) {
  438.     if (inLoadedClass()) {
  439.         throw new RMISecurityException("checksecurityaccess", provider);
  440.     }
  441.     }
  442. }
  443.